// Copyright (c) 2021 by Rockchip Electronics Co., Ltd. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "mpp_itc_rga.h"
#include <mpp_common.h>

#include <string>
#include <iostream>
using namespace std;
/**
 * RGA初始化
 * @param rga_ctx  传一个实例化变量即可
 * @return
 */
int RGA_init(rga_context *rga_ctx)
{
    rga_ctx->rga_handle = NULL;
    rga_ctx->rga_handle = dlopen("/usr/lib/librga.so", RTLD_LAZY);
    printf("rga_handle %p\n",rga_ctx->rga_handle);
    if (!rga_ctx->rga_handle)
    {
        printf("dlopen /usr/lib/librga.so failed\n");
        return -1;
    }
    rga_ctx->init_func = (FUNC_RGA_INIT)dlsym(rga_ctx->rga_handle, "c_RkRgaInit");
    rga_ctx->deinit_func = (FUNC_RGA_DEINIT)dlsym(rga_ctx->rga_handle, "c_RkRgaDeInit");
    rga_ctx->blit_func = (FUNC_RGA_BLIT)dlsym(rga_ctx->rga_handle, "c_RkRgaBlit");
    rga_ctx->init_func();
    return 0;
}

/**
 *
 * @param rga_ctx
 * @param src_fd
 * @param src_w
 * @param src_h
 * @param dst_phys
 * @param dst_w
 * @param dst_h
 */
void img_resize_fast(rga_context *rga_ctx, int src_fd, int src_w, int src_h, 
                                        uint64_t dst_phys, int dst_w, int dst_h)
{
    // printf("rga use fd, src(%dx%d) -> dst(%dx%d)\n", src_w, src_h, dst_w, dst_h);

    if (rga_ctx->rga_handle)
    {
        int ret = 0;
        rga_info_t src, dst;

        memset(&src, 0, sizeof(rga_info_t));
        src.fd = src_fd;
        src.mmuFlag = 1;
        // src.virAddr = (void *)psrc;

        memset(&dst, 0, sizeof(rga_info_t));
        dst.fd = -1;
        dst.mmuFlag = 0;

#if defined(__arm__)
        dst.phyAddr = (void *)((uint32_t)dst_phys);
#else
        dst.phyAddr = (void *)dst_phys;
#endif

        dst.nn.nn_flag = 0;

        rga_set_rect(&src.rect, 0, 0, src_w, src_h, src_w, src_h, RK_FORMAT_RGB_888);
        rga_set_rect(&dst.rect, 0, 0, dst_w, dst_h, dst_w, dst_h, RK_FORMAT_YCrCb_420_SP);

        ret = rga_ctx->blit_func(&src, &dst, NULL);
        if (ret)
        {
            printf("c_RkRgaBlit error : %s\n", strerror(errno));
        }

        return;
    }
    return;
}

/**
 *
 * @param rga_ctx
 * @param src_virt
 * @param src_w
 * @param src_h
 * @param src_format
 * @param src_rotation
 * @param dst_virt
 * @param dst_w
 * @param dst_h
 * @param dst_format
 * @param dst_rotation
 */
void img_resize_slow(rga_context *rga_ctx,
                    void *src_virt, int src_w, int src_h,FRAME_TYPE src_format,int src_rotation,
                    void *dst_virt, int dst_w, int dst_h,FRAME_TYPE dst_format,int dst_rotation)
{
    //printf("rga use virtual, src(%dx%d) -> dst(%dx%d)\n", src_w, src_h, dst_w, dst_h);

    if (rga_ctx->rga_handle){
        int ret = 0;
        rga_info_t src, dst;
        RgaSURF_FORMAT srcformat,dstformat;
        memset(&src, 0, sizeof(rga_info_t));
        src.fd = -1;
        src.mmuFlag = 1;
        src.rotation = HAL_TRANSFORM_FLIP_H;
        printf("原图形旋转方向%d \n",src.rotation);
        src.virAddr = (void *)src_virt;

        memset(&dst, 0, sizeof(rga_info_t));
        dst.fd = -1;
        dst.mmuFlag = 1;
        dst.virAddr = (void *)dst_virt;
        dst.rotation = 0;
        dst.nn.nn_flag = 0;
        printf("目标图形旋转方向%d \n",dst.rotation);
        switch (src_format){
        case MPP_FRAME_TYPE_YUV420SP:     /* YYYY... UV... (NV12)     */
            srcformat = RK_FORMAT_YCbCr_420_SP;
            break;
        case MPP_FRAME_TYPE_YUV422:       /* YYYY... UVUV... (NV16)   */
            srcformat = RK_FORMAT_VYUY_422;
            break;
        case MPP_FRAME_TYPE_YUV420SP_VU:  /* YYYY... VUVUVU... (NV21) */
            srcformat = RK_FORMAT_YCrCb_420_SP;
            break;
        case MPP_FRAME_TYPE_YUV422SP_VU:  /* YYYY... VUVUVU... (NV61) */
            srcformat = RK_FORMAT_UYVY_422;
            break;
        case MPP_FRAME_TYPE_YUV422P:      /* YYYY... UU...VV...(422P) */
            srcformat = RK_FORMAT_YVYU_422;
            break;



        case MPP_FRAME_TYPE__RGBA_8888:
            srcformat = RK_FORMAT_RGBA_8888;
            break;
        case MPP_FRAME_TYPE__RGBX_8888:
            srcformat = RK_FORMAT_RGBX_8888;
            break;
        case MPP_FRAME_TYPE__RGB_888:
            srcformat = RK_FORMAT_RGB_888;
            break;
        case MPP_FRAME_TYPE__BGRA_8888:
            srcformat = RK_FORMAT_BGRA_8888;
            break;
        case MPP_FRAME_TYPE__RGB_565:
            srcformat = RK_FORMAT_RGB_565;
            break;
        case MPP_FRAME_TYPE__RGBA_5551:
            srcformat = RK_FORMAT_RGBA_5551;
            break;
        case MPP_FRAME_TYPE__RGBA_4444:
            srcformat = RK_FORMAT_RGBA_4444;
            break;
        case MPP_FRAME_TYPE__BGR_888:
            srcformat = RK_FORMAT_BGR_888;
            break;
        case MPP_FRAME_TYPE__BGRX_8888:
            srcformat = RK_FORMAT_BGRX_8888;
            break;
        case MPP_FRAME_TYPE__BGR_565:
            srcformat = RK_FORMAT_BGR_565;
            break;
        case MPP_FRAME_TYPE__BGRA_5551:
            srcformat = RK_FORMAT_BGRA_5551;
            break;
        case MPP_FRAME_TYPE__BGRA_4444:
            srcformat = RK_FORMAT_BGRA_4444;
            break;
        default:
            printf("不支持的转换格式\n");
            return ;
        }

        switch (dst_format)
        {
        case MPP_FRAME_TYPE_YUV420SP:     /* YYYY... UV... (NV12)     */
            dstformat = RK_FORMAT_YCbCr_420_SP;
            break;
        case MPP_FRAME_TYPE_YUV422:       /* YYYY... UVUV... (NV16)   */
            dstformat = RK_FORMAT_VYUY_422;
            break;
        case MPP_FRAME_TYPE_YUV420SP_VU:  /* YYYY... VUVUVU... (NV21) */
            dstformat = RK_FORMAT_YCrCb_420_SP;
            break;
        case MPP_FRAME_TYPE_YUV422SP_VU:  /* YYYY... VUVUVU... (NV61) */
            dstformat = RK_FORMAT_UYVY_422;
            break;
        case MPP_FRAME_TYPE_YUV422P:      /* YYYY... UU...VV...(422P) */
            dstformat = RK_FORMAT_YVYU_422;
            break;



        case MPP_FRAME_TYPE__RGBA_8888:
            dstformat = RK_FORMAT_RGBA_8888;
            break;
        case MPP_FRAME_TYPE__RGBX_8888:
            dstformat = RK_FORMAT_RGBX_8888;
            break;
        case MPP_FRAME_TYPE__RGB_888:
            dstformat = RK_FORMAT_RGB_888;
            break;
        case MPP_FRAME_TYPE__BGRA_8888:
            dstformat = RK_FORMAT_BGRA_8888;
            break;
        case MPP_FRAME_TYPE__RGB_565:
            dstformat = RK_FORMAT_RGB_565;
            break;
        case MPP_FRAME_TYPE__RGBA_5551:
            dstformat = RK_FORMAT_RGBA_5551;
            break;
        case MPP_FRAME_TYPE__RGBA_4444:
            dstformat = RK_FORMAT_RGBA_4444;
            break;
        case MPP_FRAME_TYPE__BGR_888:
            dstformat = RK_FORMAT_BGR_888;
            break;
        case MPP_FRAME_TYPE__BGRX_8888:
            dstformat = RK_FORMAT_BGRX_8888;
            break;
        case MPP_FRAME_TYPE__BGR_565:
            dstformat = RK_FORMAT_BGR_565;
            break;
        case MPP_FRAME_TYPE__BGRA_5551:
            dstformat = RK_FORMAT_BGRA_5551;
            break;
        case MPP_FRAME_TYPE__BGRA_4444:
            dstformat = RK_FORMAT_BGRA_4444;
            break;
        default:
            printf("不支持的转换格式\n");
            return ;
        }
        
        
        rga_set_rect(&src.rect, 0, 0, src_w, src_h, src_w, src_h,srcformat);
        rga_set_rect(&dst.rect, 0, 0, dst_w, dst_h, dst_w, dst_h,dstformat) ;

        ret = rga_ctx->blit_func(&src, &dst, NULL);
        if (ret)
        {
            printf("c_RkRgaBlit error : %s\n", strerror(errno));
        }

        return;
    }
    return;
}




int RGA_deinit(rga_context *rga_ctx)
{
    if(rga_ctx->rga_handle)
    {
        dlclose(rga_ctx->rga_handle);
        rga_ctx->rga_handle = NULL;
    }
}



class mpp_image
{
public:
    mpp_image();
    ~mpp_image();
    RET_CODE mpp_image_init(int srcFd,int srcChannel,void *src,size_t srcSize,
                            uint64_t dstFd,int dstChannel,void *dst,size_t dstSize);
    RET_CODE mpp_image_process(const IMAGE_PROCESS_INFO_T *info);
    RET_CODE mpp_image_deInit();

private:
    rga_context rga_ctx;


    int srcFd;
    void *src;
    size_t srcSize;
    int srcChannel;

    //IMAGE_SIZE_T srcImgSize; //--原图尺寸

    //RgaSURF_FORMAT srcFormat;    //--原图的格式

    //IMAGE_SIZE_T dstImgSize; //--目标尺寸

    //RgaSURF_FORMAT dstFormat;    //--目标图的格式

    uint64_t dstFd;
    void *dst;
    size_t dstSize;
    int dstChannel;
};
mpp_image::mpp_image():srcFd(-1),
                       src(NULL),
                       srcSize(0),
                       srcChannel(-1),
                       

                       dstFd(0),
                       dst(NULL),
                       dstSize(0),
                       dstChannel(-1)
{   
    memset(&rga_ctx,0x00,sizeof(rga_context));

    this->rga_ctx.rga_handle = NULL;
    this->rga_ctx.rga_handle = dlopen("/usr/lib/librga.so", RTLD_LAZY);
    
    if (!this->rga_ctx.rga_handle){
        printf("dlopen /usr/lib/librga.so failed\n");
        return ;
    }
    //cout<<"rga_handle  "<<(int )this->rga_ctx.rga_handle<<endl;;

    this->rga_ctx.init_func = (FUNC_RGA_INIT)dlsym(this->rga_ctx.rga_handle, "c_RkRgaInit");
    this->rga_ctx.deinit_func = (FUNC_RGA_DEINIT)dlsym(this->rga_ctx.rga_handle, "c_RkRgaDeInit");
    this->rga_ctx.blit_func = (FUNC_RGA_BLIT)dlsym(this->rga_ctx.rga_handle, "c_RkRgaBlit");
    if(this->rga_ctx.init_func){
        
        this->rga_ctx.init_func();
        cout<<"初始化完毕图像处理单元"<<endl;
    }
    else{
        cout<<"无法找到实例函数 c_RkRgaInit"<<endl;
    }
    
}
mpp_image::~mpp_image()
{
    if (this->rga_ctx.rga_handle){
        dlclose(this->rga_ctx.rga_handle);
    }
}
RET_CODE mpp_image::mpp_image_process(const IMAGE_PROCESS_INFO_T *info)
{
    RET_CODE ret = MPP_RET_CODE_FAILURE;
    rga_info_t src, dst;
    IMAGE_SIZE_T srcSize,dstSize; //--原图尺寸  目标尺寸

    uint64_t dstFd = -1;

    RgaSURF_FORMAT srcformat,dstformat;
    int src_x = 0,src_y= 0,srcClipping_width= 0,srcClipping_hight= 0;

    if (!this->rga_ctx.rga_handle || !this->rga_ctx.init_func  || !this->rga_ctx.deinit_func ||  !this->rga_ctx.blit_func){
        return MPP_RET_CODE_FAILURE;
    }



    if (!this->rga_ctx.rga_handle){
        printf("dlopen /usr/lib/librga.so failed\n");
        return MPP_RET_CODE_FAILURE;
    }
    if(!info){
        return MPP_RET_CODE_FAILURE;
    }
    memset(&src,0x00,sizeof(rga_info_t));
    memset(&dst,0x00,sizeof(rga_info_t));


    srcClipping_width = info->srcRecSize.width;
    srcClipping_hight = info->srcRecSize.hight;
    switch (info->srcFormat)
    {
        case MPP_FRAME_TYPE_YUV420SP:     /* YYYY... UV... (NV12)     */
            srcformat = RK_FORMAT_YCbCr_420_SP;
            break;
        case MPP_FRAME_TYPE_YUV422:       /* YYYY... UVUV... (NV16)   */
            srcformat = RK_FORMAT_VYUY_422;
            break;
        case MPP_FRAME_TYPE_YUV420SP_VU:  /* YYYY... VUVUVU... (NV21) */
            srcformat = RK_FORMAT_YCrCb_420_SP;
            break;
        case MPP_FRAME_TYPE_YUV422SP_VU:  /* YYYY... VUVUVU... (NV61) */
            srcformat = RK_FORMAT_UYVY_422;
            break;
        case MPP_FRAME_TYPE_YUV422P:      /* YYYY... UU...VV...(422P) */
            srcformat = RK_FORMAT_YVYU_422;
            break;



        case MPP_FRAME_TYPE__RGBA_8888:
            srcformat = RK_FORMAT_RGBA_8888;
            break;
        case MPP_FRAME_TYPE__RGBX_8888:
            srcformat = RK_FORMAT_RGBX_8888;
            break;
        case MPP_FRAME_TYPE__RGB_888:
            srcformat = RK_FORMAT_RGB_888;
            break;
        case MPP_FRAME_TYPE__BGRA_8888:
            srcformat = RK_FORMAT_BGRA_8888;
            break;
        case MPP_FRAME_TYPE__RGB_565:
            srcformat = RK_FORMAT_RGB_565;
            break;
        case MPP_FRAME_TYPE__RGBA_5551:
            srcformat = RK_FORMAT_RGBA_5551;
            break;
        case MPP_FRAME_TYPE__RGBA_4444:
            srcformat = RK_FORMAT_RGBA_4444;
            break;
        case MPP_FRAME_TYPE__BGR_888:
            srcformat = RK_FORMAT_BGR_888;
            break;
        case MPP_FRAME_TYPE__BGRX_8888:
            srcformat = RK_FORMAT_BGRX_8888;
            break;
        case MPP_FRAME_TYPE__BGR_565:
            srcformat = RK_FORMAT_BGR_565;
            break;
        case MPP_FRAME_TYPE__BGRA_5551:
            srcformat = RK_FORMAT_BGRA_5551;
            break;
        case MPP_FRAME_TYPE__BGRA_4444:
            srcformat = RK_FORMAT_BGRA_4444;
            break;
        default:
            printf("不支持的转换格式\n");
            return ret;
    }
    switch (info->dstFormat)
    {
        case MPP_FRAME_TYPE_YUV420SP:     /* YYYY... UV... (NV12)     */
            dstformat = RK_FORMAT_YCbCr_420_SP;
            break;
        case MPP_FRAME_TYPE_YUV422:       /* YYYY... UVUV... (NV16)   */
            dstformat = RK_FORMAT_VYUY_422;
            break;
        case MPP_FRAME_TYPE_YUV420SP_VU:  /* YYYY... VUVUVU... (NV21) */
            dstformat = RK_FORMAT_YCrCb_420_SP;
            break;
        case MPP_FRAME_TYPE_YUV422SP_VU:  /* YYYY... VUVUVU... (NV61) */
            dstformat = RK_FORMAT_UYVY_422;
            break;
        case MPP_FRAME_TYPE_YUV422P:      /* YYYY... UU...VV...(422P) */
            dstformat = RK_FORMAT_YVYU_422;
            break;



        case MPP_FRAME_TYPE__RGBA_8888:
            dstformat = RK_FORMAT_RGBA_8888;
            break;
        case MPP_FRAME_TYPE__RGBX_8888:
            dstformat = RK_FORMAT_RGBX_8888;
            break;
        case MPP_FRAME_TYPE__RGB_888:
            dstformat = RK_FORMAT_RGB_888;
            break;
        case MPP_FRAME_TYPE__BGRA_8888:
            dstformat = RK_FORMAT_BGRA_8888;
            break;
        case MPP_FRAME_TYPE__RGB_565:
            dstformat = RK_FORMAT_RGB_565;
            break;
        case MPP_FRAME_TYPE__RGBA_5551:
            dstformat = RK_FORMAT_RGBA_5551;
            break;
        case MPP_FRAME_TYPE__RGBA_4444:
            dstformat = RK_FORMAT_RGBA_4444;
            break;
        case MPP_FRAME_TYPE__BGR_888:
            dstformat = RK_FORMAT_BGR_888;
            break;
        case MPP_FRAME_TYPE__BGRX_8888:
            dstformat = RK_FORMAT_BGRX_8888;
            break;
        case MPP_FRAME_TYPE__BGR_565:
            dstformat = RK_FORMAT_BGR_565;
            break;
        case MPP_FRAME_TYPE__BGRA_5551:
            dstformat = RK_FORMAT_BGRA_5551;
            break;
        case MPP_FRAME_TYPE__BGRA_4444:
            dstformat = RK_FORMAT_BGRA_4444;
            break;
        default:
            printf("不支持的转换格式\n");
            return MPP_RET_CODE_FAILURE;
    }
        
      
    
    memcpy(&srcSize,&info->srcRecSize,sizeof(IMAGE_SIZE_T));
    memcpy(&dstSize,&info->dstRecSize,sizeof(IMAGE_SIZE_T));

    if(info->Img_ProcessFlg &  IMAGE_PROCESS_ROTAION){
        if(info->img_rotaion & IMAGE_ROTAION_HOR)
            src.rotation |= HAL_TRANSFORM_FLIP_H;
        if(info->img_rotaion & IMAGE_ROTAION_VER)
            src.rotation |= HAL_TRANSFORM_FLIP_V;
        if(info->img_rotaion & IMAGE_ROTAION_90){
            uint32_t tmp = 0;      // 90度和270度旋转需要交换宽度和高度的数据
            src.rotation |= HAL_TRANSFORM_ROT_90;
            tmp = dstSize.hight;    
            dstSize.hight = dstSize.width;
            dstSize.width = tmp;
        }
            
        if(info->img_rotaion & IMAGE_ROTAION_180)
            src.rotation |= HAL_TRANSFORM_ROT_180;
        if(info->img_rotaion & IMAGE_ROTAION_270){
            src.rotation |= HAL_TRANSFORM_ROT_270;
            uint32_t tmp = 0;
            tmp = dstSize.hight;
            dstSize.hight = dstSize.width;
            dstSize.width = tmp;
        }
            
    }
    if(info->Img_ProcessFlg &  IMAGE_PROCESS_CLIPPING){
        src_x = info->img_clipping.src_x ;
        src_y = info->img_clipping.src_y ;// --原图需要裁剪的x,y
        srcClipping_width =info->img_clipping.src_clipping_width;//--在原图中需要裁剪的宽度 高度
        srcClipping_hight =info->img_clipping.src_clipping_hight;
    }
    if(info->Img_ProcessFlg &  IMAGE_PROCESS_FORMAT_CONVER){
        cout<<"原图格式"<<std::hex<<srcformat<<endl;
        cout<<"目标图格式"<<std::hex<<dstformat<<endl;
    }
    if(info->Img_ProcessFlg & IMAGE_PROCESS_ZOOM){ //--缩放
        //srcSize.hight = info->img_zoom.srcSize.hight;
        //srcSize.width = info->img_zoom.srcSize.width;
        src_x = 0;
        src_y = 0;

        if(info->Img_ProcessFlg &  IMAGE_PROCESS_CLIPPING){   //--如果缩放里面又需要裁剪
            src_x = info->img_clipping.src_x ;
            src_y = info->img_clipping.src_y ;// --原图需要裁剪的x,y
            srcClipping_width =info->img_clipping.src_clipping_width;//--在原图中需要裁剪的宽度 高度
            srcClipping_hight =info->img_clipping.src_clipping_hight;
        }

    }
    if(info->Img_ProcessFlg &  IMAGE_PROCESS_OVERLAY) {
           
            dst.blend =  0xFF0100;
            
    }
    // --以下是设置瑞芯微的参数能拿到硬件，参数设置有点乱，需要详细参考瑞芯微的手册
    if(this->srcFd >=0){        // --这个参数能拿到文件描述符的
        src.fd = this->srcFd;
        src.mmuFlag = 1;
        cout<<"原图像文件描述符:"<<this->dstFd<<endl;
    }else{                      // --这个参数不能拿到文件描述符的，只能在用户内存空间中转换
        src.fd = -1;  
        src.mmuFlag = 1;  
        src.virAddr = (void *)this->src;
    }
    

    if(this->dstFd > 0){    // --这个参数能拿到文件描述符的
#if defined(__arm__)
        dst.phyAddr = (void *)((uint32_t)dst_phys);
#else
        dst.phyAddr = (void *)this->dstFd;
#endif
        dst.fd = -1;
        dst.mmuFlag = 0;
        cout<<"目标图像文件描述符:"<<this->dstFd<<endl;
    }else{                  // --这个参数不能拿到文件描述符的，只能在用户内存空间中转换
        dst.virAddr = (void *)this->dst;
        dst.fd = -1;
        dst.mmuFlag = 1;
    }
    
    dst.nn.nn_flag = 0;

    // -- 以下是参数赋值
    printf("src_x=%d, src_y=%d, srcClipping_width=%d, srcClipping_hight=%d,"\
                "nfo->srcRecSize.width=%d, info->srcRecSize.hight=%d,srcformat=%d \n" ,
                src_x, src_y, srcClipping_width, srcClipping_hight, 
                info->srcRecSize.width, info->srcRecSize.hight,srcformat);
    printf("dstSize.width=%d, dstSize.hight=%d, dstSize.width=%d, dstSize.hight=%d,dstformat=%d \n" ,
                dstSize.width, dstSize.hight, dstSize.width, dstSize.hight,dstformat);


    rga_set_rect(&src.rect, src_x, src_y, srcClipping_width, srcClipping_hight, 
                                info->srcRecSize.width, info->srcRecSize.hight,srcformat);                      
    rga_set_rect(&dst.rect, 0, 0, dstSize.width, dstSize.hight, dstSize.width, dstSize.hight,dstformat) ;
    // --执行 ，执行完这个函数之后图像就能裁剪，缩放了
    int tmpret = this->rga_ctx.blit_func(&src, &dst, NULL);
    if (tmpret){
        printf("c_RkRgaBlit error : %s\n", strerror(errno));
    }

    return MPP_RET_CODE_OK;
}

RET_CODE mpp_image::mpp_image_init(int srcFd,int srcChannel,void *src,size_t srcSize,
                                   uint64_t dstFd,int dstChannel,void *dst,size_t dstSize)
{
    // this->rga_ctx.rga_handle = NULL;
    // this->rga_ctx.rga_handle = dlopen("/usr/lib/librga.so", RTLD_LAZY);
    
    // if (!this->rga_ctx.rga_handle){
    //     printf("dlopen /usr/lib/librga.so failed\n");
    //     return MPP_RET_CODE_FAILURE;
    // }
    // cout<<"rga_handle  "<<std::hex<<this->rga_ctx.rga_handle<<endl;
    

    if (!this->rga_ctx.rga_handle || !this->rga_ctx.init_func  || !this->rga_ctx.deinit_func ||  !this->rga_ctx.blit_func){
        return MPP_RET_CODE_FAILURE;
    }




    this->srcFd = srcFd;
    this->src = src;
    this->srcChannel = srcChannel;  // --瑞芯微平台没有像海思那样的通道的概念，此函数无用
    this->srcSize  = srcSize;

    //memcpy(&this->srcImgSize,srcImgSize,sizeof(IMAGE_SIZE_T));

    //memcpy(&this->dstImgSize,dstImgSize,sizeof(IMAGE_SIZE_T));

    if(dstFd == -1 || dstFd == 0)
        this->dstFd = 0;   
    else  
        this->dstFd =  dstFd;
        
    this->dst   = dst;
    this->dstChannel = dstChannel; // --瑞芯微平台没有像海思那样的通道的概念，此函数无用
    this->dstSize  = dstSize;

    // this->rga_ctx.init_func = (FUNC_RGA_INIT)dlsym(this->rga_ctx.rga_handle, "c_RkRgaInit");
    // this->rga_ctx.deinit_func = (FUNC_RGA_DEINIT)dlsym(this->rga_ctx.rga_handle, "c_RkRgaDeInit");
    // this->rga_ctx.blit_func = (FUNC_RGA_BLIT)dlsym(this->rga_ctx.rga_handle, "c_RkRgaBlit");
    // if(this->rga_ctx.init_func){
        
    //     this->rga_ctx.init_func();
    //     cout<<"初始化完毕图像处理单元"<<endl;
    // }
    // else{
    //     cout<<"无法找到实例函数 c_RkRgaInit"<<endl;
    // }

    return MPP_RET_CODE_OK;
}

RET_CODE  mpp_image::mpp_image_deInit()
{
    if(this->rga_ctx.rga_handle)
        this->rga_ctx.deinit_func();
    return MPP_RET_CODE_OK;
}

static RET_CODE image_process_init(const void *ctx,
                        int srcFd,int srcChannel,void *src,size_t srcSize,
                        uint64_t dstFd,int dstChannel,void *dst,size_t dstSize)
                        
{
    if(!ctx){
        return MPP_RET_CODE_FAILURE;
    }
    mpp_image *m_mpp_image = (mpp_image *)ctx;
    return m_mpp_image->mpp_image_init( srcFd, srcChannel, src, srcSize,
                                        dstFd, dstChannel, dst, dstSize);
}
static RET_CODE image_process(const void *ctx,const IMAGE_PROCESS_INFO_T *info)
{
    if(!ctx){
        return MPP_RET_CODE_FAILURE;
    }
    mpp_image *m_mpp_image = (mpp_image *)ctx;
    return m_mpp_image->mpp_image_process(info);
}
static RET_CODE image_process_deInit(const void *ctx)
{
    if(!ctx){
        return MPP_RET_CODE_FAILURE;
    }
    mpp_image *m_mpp_image = (mpp_image *)ctx;
    return m_mpp_image->mpp_image_deInit();
}
static char *  image_process_version(void)
{
    return (char *)"MPP_IMAGE_V1.0.0";
}
MPP_IMAGE_PROCESS_T * create_image_process(void)
{
    MPP_IMAGE_PROCESS_T *img_process = new MPP_IMAGE_PROCESS_T;
    printf("创建图像处理单元\n");
    if(img_process){
         mpp_image *m_mpp_image = new mpp_image();
         if(m_mpp_image){
            img_process->ctx = (void *)m_mpp_image;
            img_process->image_process = image_process;
            img_process->image_process_deInit = image_process_deInit;
            img_process->image_process_init = image_process_init; 
            img_process->image_process_version = image_process_version;
             return img_process;
         }else{
             delete img_process;
        }
        
    }
    return NULL;
}
void image_process_destroy(MPP_IMAGE_PROCESS_T * dec)
{
    if(dec){
        mpp_image *m_mpp_image = (mpp_image*)dec->ctx;
        if(m_mpp_image)
            delete m_mpp_image;
        delete dec;
    }
}
